//
// Created by Administrator on 2019/6/6 0006.
//

#ifndef FFMPEGDEMO_BASECHANNEL_H
#define FFMPEGDEMO_BASECHANNEL_H

extern "C" {
#include <libavcodec/avcodec.h>
};
#include "safe_queue.h"
#include "JavaCallback.h"

class BaseChannel {

public:
    BaseChannel(int id, JavaCallback *javaCallback, AVCodecContext * avCodecContext, AVRational time_base) :
    channelId(id), javaCallback(javaCallback), avCodecContext(avCodecContext), time_base(time_base) {

        pkt_queue.setReleaseHandle(releaseAvPacket);
        frame_queue.setReleaseHandle(releaseAvFrame);
    }
    static void releaseAvPacket(AVPacket *&packet) {
        if (packet) {
            av_packet_free(&packet);
            packet = 0;
        }
    }

    static void releaseAvFrame(AVFrame *&frame) {
        if (frame) {
            av_frame_free(&frame);
            frame = 0;
        }
    }

    virtual ~BaseChannel() {
        if (avCodecContext) {
            avcodec_close(avCodecContext);
            avcodec_free_context(&avCodecContext);
            avCodecContext = 0;
        }
        pkt_queue.clear();
        frame_queue.clear();
    }

    void clear() {
        pkt_queue.clear();
        frame_queue.clear();
    }

    void startWork() {
        pkt_queue.setWork(1);
        frame_queue.setWork(1);
    }

    void stopWork() {
        pkt_queue.setWork(0);
        frame_queue.setWork(0);
    }


    virtual void play() = 0;
    virtual void stop() = 0;

    SafeQueue<AVPacket *> pkt_queue;
    SafeQueue<AVFrame *> frame_queue;
    volatile int channelId;
    volatile bool isPlaying;
    AVCodecContext *avCodecContext;
    JavaCallback *javaCallback;
    AVRational time_base;
    double clock = 0;
};
#endif //FFMPEGDEMO_BASECHANNEL_H
